package com.social.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rabbitmq.client.Channel;
import com.social.dao.VolunteerRegisterDao;
import com.social.pojo.Result;
import com.social.pojo.VolunteerRegister;
import com.social.pojo.Volunteering;
import com.social.service.VolunteerRegisterService;
import com.social.service.VolunteerService;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.io.IOException;
import java.time.LocalDateTime;

import static com.social.constant.MessageConstant.*;
import static com.social.constant.MessageConstant.OPERATE_DATA_SUCCESS;
import static com.social.constant.RabbitMqConstants.*;
import static com.social.constant.RedisConstants.*;
import static com.social.constant.StateConstant.VOLUNTEER_REGISTER_STATE_ACCEPT;
import static com.social.constant.StateConstant.VOLUNTEER_REGISTER_STATE_REJECT;

/**
 * @className: VolunteerRegisterServiceImpl
 * @description: TODO 类描述
 * @author: XiaoXu
 * @date: 2022/12/11 20:09
 **/
@Service
public class VolunteerRegisterServiceImpl extends ServiceImpl<VolunteerRegisterDao, VolunteerRegister> implements VolunteerRegisterService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;



    private VolunteerService volunteerService;

    @Resource
    private RabbitTemplate rabbitTemplate;
    @Override
    public Result acceptApply(Long id) {
        //TODO 报名判断
        VolunteerRegister apply = getById(id);
        String key = VOLUNTEER_ID_NUMBER + apply.getActivityId();
        String json = stringRedisTemplate.opsForValue().get(key);
        Integer number = JSONUtil.toBean(json, Integer.class);

        String key1 = VOLUNTEER_ID_REGISTER + apply.getActivityId();
        String registerJson = stringRedisTemplate.opsForValue().get(key1);
        Integer register = JSONUtil.toBean(registerJson, Integer.class);
        if(register >= number){
            return Result.fail(OPERATE_DATA_FAIL,REGISTER_ACTIVITY_EXCEED);
        }

        boolean isSuccess = volunteerService.update()
                .setSql("register = register + 1")
                .eq("id", apply.getActivityId())
                .update();
        if(!isSuccess){
            return Result.fail(OPERATE_DATA_FAIL,REGISTER_ACTIVITY_EXCEED);
        }
        stringRedisTemplate.opsForValue().increment(key1);
        //TODO 消息隊列未完
        rabbitTemplate.convertAndSend(ACTIVITY_EXCHANGE,VOLUNTEER_REGISTER_ROUTING,apply);

        boolean update = update().setSql("state = " + VOLUNTEER_REGISTER_STATE_ACCEPT)
                .eq("id", id).update();

        return Result.ok(OPERATE_DATA_SUCCESS);
    }

    @RabbitListener(queues = VOLUNTEER_REGISTER_QUEUE)
    public void applyHandler(Message message, Channel channel) throws IOException {
        String json = new String(message.getBody());
        try {
            VolunteerRegister register = JSONUtil.toBean(json, VolunteerRegister.class);

            register.setState(VOLUNTEER_REGISTER_STATE_ACCEPT);
            boolean isSuccess = updateById(register);
            if (!isSuccess){
                throw new Exception();
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        }catch (Exception e){
            log.error("异常消费",e.fillInStackTrace());
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
        }
    }


    @Override
    public Result register(Long id,String letter) {
        //查找活动已报名人数
        String key = VOLUNTEER_ID_NUMBER + id;
        String json = stringRedisTemplate.opsForValue().get(key);
        if(json == null){
            Long count = query().eq("activityId", id).eq("state", VOLUNTEER_REGISTER_STATE_ACCEPT).count();
            json = JSONUtil.toJsonStr(count);
            stringRedisTemplate.opsForValue().set(key,json);
        }
        Integer registerNum = JSONUtil.toBean(json, Integer.class);
        //查找活动报名人数上限
        String key1 = VOLUNTEER_ID_REGISTER + id;
        String registerJson = stringRedisTemplate.opsForValue().get(key1);
        if(registerJson == null){
            Volunteering one = volunteerService.getById(id);
            registerJson = JSONUtil.toJsonStr(one.getV_number());
            stringRedisTemplate.opsForValue().set(key1,registerJson);
        }
        Integer number = JSONUtil.toBean(registerJson, Integer.class);

        if (registerNum >= number){
            return Result.fail(OPERATE_DATA_FAIL,REGISTER_ACTIVITY_EXCEED);
        }

        VolunteerRegister register = new VolunteerRegister();
        register.setActivityId(id);
        register.setLetter(letter);
        LocalDateTime now = LocalDateTime.now();
        register.setRegisterTime(now);
        register.setUpdateTime(now);

        boolean save = save(register);
        if (!save){
            return Result.fail(OPERATE_DATA_FAIL,REGISTER_ACTIVITY_FAIL);
        }

        return Result.ok(OPERATE_DATA_SUCCESS);
    }

    @Override
    public Result rejectApply(Long id) {
        boolean isSuccess = update().setSql("state = " + VOLUNTEER_REGISTER_STATE_REJECT).eq("id", id).update();
        if(!isSuccess){
            return Result.fail(OPERATE_DATA_FAIL,"失败，请重试");
        }
        return Result.ok(OPERATE_DATA_SUCCESS);
    }
}
